import React, { Component } from 'react';
import { Upload, Icon, Modal, message } from 'antd';
import styles from './MultiUpload.less'; // 样式


/*
const ossUploadConfig = {
  // type: 'oss',
  imageUploadServerHost: 'https://www.mocky.io/v2/5cc8019d300000980a055e76', // 图片上传服务地址
  imageShowServiceHost: '', // 图片查看地址前缀
  totalNum: 5, // 最大上传数量
  // 回显图片的路径 半路径 ;分隔
  value:'avatar/2018-10-10/38.jpg;avatar/2018-10-10/1080_1920.jpg',
  // maxSize: 1024, // 图片大小限制1MB
  // minWidth: 100, // 图片宽度限制
  // maxWidth: 100,
  // minHeight: 100, // 图片高度限制
  // maxHeight: 100,
  onChange={this.onChange} // 图片上传成功时的回调 参数为图片的半路径;分隔的一个字符串
};

<MultiUpload
  getSign={this.getOSSSign} // 获取签名的方法 Promise
  // 获取签名getSign方法 的第四个参数 供获取签名时 自定义入参
  extraParam={{bizName:"avatar"}}
  {...ossUploadConfig}
/>
*/
class MultiUpload extends Component {
  static defaultProps = {
    totalNum: 10, // 上传数量限制
    value: '',
    onChange: () => { },
    supportSort: false,
    maxSize: 2048,
    imageShowServiceHost: '',
    imageUploadServerHost: '',
    getSign: () => { },
    roleUser: 'admin'
  };

  constructor(props) {
    super(props);
    this.state = {
      previewVisible: false, // 弹出层关闭X控制
      roleAuthor: {'admin': true, 'b': true}, // 指定角色才可使用
      previewImage: '',
      fileList: [
        {
          uid: '-1',
          name: 'xxx.png',
          status: 'done',
          url: 'https://zos.alipayobjects.com/rmsportal/jkjgkEfvpUPVyRjUImniVslZfWPnJuuZ.png',
        },
      ],
    };
  }

  // 弹出层图片-右上角关闭事件
  handleCancel = () => this.setState({ previewVisible: false });

  // 获取批量图片路径 用;分隔
  getImages = deleteFileName => {
    const { onChange } = this.props;
    const { fileList } = this.state;
    let result = [];
    fileList.map(item => {
      if (item.name) {
        result.push(item.name); // 把上传成功的每张图片名称加入数组xxx.png
      }
      return null;
    });

    // 当有图片移除时
    if (deleteFileName) {
      result = this.ArrayRemoveByValue(result, deleteFileName);
    }
    onChange(result.join(';')); // 把数组中的名称切成;分号
  };

  /**
   * 获取formData 数据
   */
  getData = () => {
    const { formData } = this.state;
    return formData;
  };

  getPreNextInfo = fileName => {
    const { fileList } = this.state;
    let currentIndex = 0;
    let needPre = true;
    let needNext = true;

    fileList.map((item, index) => {
      if (item.name === fileName) {
        currentIndex = index;
      }
      return null;
    });
    if (currentIndex === 0) {
      needPre = false;
    }
    if (currentIndex === fileList.length - 1) {
      needNext = false;
    }

    return {
      currentIndex,
      needPre,
      needNext,
    };
  };

  // 移除图片的回调
  handleRemove = file => {
    const { roleUser } = this.props
    const roleAuthor = this.state.roleAuthor;
    // 指定权限才可以移除
    if (roleAuthor[roleUser]) {
      let deleteFileName = '';
      if (file && file.response) {
        deleteFileName = file.response.data;
      } else if (file && file.name) {
        deleteFileName = file.name;
      }
      this.getImages(deleteFileName);
      return true;
    }

    message.warn(`没有权限，无法移除`);
    return false;
  };

  // 处理移除图片事件
  ArrayRemoveByValue = (arr, val) => {
    for (let i = 0; i < arr.length; i += 1) {
      if (arr[i] === val) {
        arr.splice(i, 1); // 找到指定位置移除一张
        break;
      }
    }
    return arr;
  };

  /**
   *  将正在上传的批量图片 与已经上传的图片进行数据合并
   *  1: 遍历state中的fileList 将status为done优先push结果集数组
   *  2: 遍历上传列表中的fileList 如果结果集数组中不存在 就push进结果集数组
   */
  mergeFileList = upFileList => {
    const { fileList } = this.state;
    const result = [];

    const isInResult = file => {
      let flag = false;
      result.map(item => {
        if (item.uid === file.uid) {
          flag = true;
        }
        return null;
      });
      return flag;
    };
    // 已上传文件先添加
    fileList.map(item => {
      if (!isInResult(item)) {
        if (item.status === 'done') {
          result.push(item);
        }
      }
      return null;
    });
    // 正在上传的添加到后面
    upFileList.map(item => {
      if (!isInResult(item)) {
        result.push(item);
      }
      return null;
    });

    return result;
  };

  // 上传前处理事件
  beforeUpload = (file, fileList) => {
    const { state } = this;
    // 限制图片格式
    const suffixMap = new RegExp(/^image\/jpeg|gif|jpg|png$/, 'i');
    const {
      maxSize,
      getSign,
      extraParam,
      totalNum,
      minWidth,
      maxWidth,
      minHeight,
      maxHeight,
    } = this.props;
    const defaultMaxSize = 2048; // 默认最大文件大

    return new Promise((resolve, reject) => {
      if (state.fileList.length + fileList.length > totalNum) {
        message.warn(`最多上传${totalNum}张图片 还能上传${totalNum - state.fileList.length}张`);
        reject();
        return false;
      }

      if (!suffixMap.test(file.type)) {
        message.error('只能上传图片文件，可以是jpg/png/gif/bmp/webp格式!');
        reject();
        return false;
      }

      if (file.size / 1024 > (maxSize || defaultMaxSize)) {
        message.error(`图片大小不能超过${maxSize || defaultMaxSize}kb!`);
        reject();
        return false;
      }
      // 创建一个二进制对象流
      const imgBlobUrl = URL.createObjectURL(file);
      const img = document.createElement('img');

      console.log('开始上传')
      // 异步图片加载
      img.onload = async () => {
        const { width, height } = img;
        const showError = () => {
          message.error(`您上传的图片尺寸(${width} * ${height}) 与要求不符 请重新上传`);
          reject();
        };

        // 判断图片是否超出限制
        if (
          (minWidth && width < minWidth) ||
          (maxWidth && width > maxWidth) ||
          (minHeight && height < minHeight) ||
          (maxHeight && height > maxHeight)
        ) {
          showError();
          return false;
        }

        // 获取签名验证
        // const signData = await getSign(suffixMap.test(file.type), width, height, extraParam);

        // if (!signData) {
        //   reject();
        //   return false;
        // }
        // signData.fileName = file.name;

        // this.setState({ formData: signData }, resolve);
        resolve()
      };

      img.src = imgBlobUrl;
    });
  };

  // 点击预览图标时的回调
  handlePreview = file => {
    const { currentIndex, needPre, needNext } = this.getPreNextInfo(file.name);

    this.setState({
      preview: true,
      previewImage: file.url || file.thumbUrl,
      currentIndex,
      needPre,
      needNext,
    });
  };


  // 关闭预览判断
  handlePreviewClose = () => {
    this.setState({
      preview: false,
    });
  };

  // 查看下一张图
  showNextImage = index => {
    const { fileList } = this.state;
    const nextIndex = index + 1;
    const file = fileList[nextIndex];
    const { currentIndex, needPre, needNext } = this.getPreNextInfo(file.name);
    this.setState({
      previewImage: file.url || file.thumbUrl,
      currentIndex,
      needPre,
      needNext,
    });
  };

  // 查看上一张图
  showPreImage = index => {
    const { fileList } = this.state;
    const nextIndex = index - 1;
    const file = fileList[nextIndex];
    const { currentIndex, needPre, needNext } = this.getPreNextInfo(file.name);
    this.setState({
      previewImage: file.url || file.thumbUrl,
      currentIndex,
      needPre,
      needNext,
    });
  };

  // 获取上传按钮
  uploadButton = () => {
    const { loading } = this.state;
    return (
      <div className={styles.uploadImg}>
        <Icon style={{ fontSize: 28 }} type={loading ? 'loading' : 'plus'} />
        <div className="ant-upload-text">上传图片</div>
      </div>
    );
  };

  // 上传动作的回调
  handleChange = info => {
    const { type } = this.props;
    const { file, fileList } = info;

    // 图片上传成功后，fileList数组中的 thumbUrl 中保存的是图片的base64字符串，这种情况，导致的问题是：图片上传成功后，点击图片缩略图，浏览器会会卡死。而下面这行代码，可以解决该bug。
    // fileList.forEach(imgItem => {
    //   if (imgItem && imgItem.status === 'done' && imgItem.response && imgItem.response.imgUrl) {
    //     // eslint-disable-next-line no-param-reassign
    //     imgItem.thumbUrl = imgItem.response.imgUrl;
    //   }
    // });

    this.setState({
      fileList: this.mergeFileList(fileList), // 合并图片
    });

    if (file.status === 'uploading') {
      this.setState({ loading: true });
      return;
    }

    // 图片上传完成
    if (file.status === 'done') {
      let flag = true;
      console.log('上传完成')
      if (type === 'oss') {
        const responseData = file.response.data;
        fileList.map((item, index) => {
          if (item.name === file.name) {
            fileList[index].name = responseData.key;
          }
          if (item.status !== 'done') {
            flag = false;
          }
          return null;
        });
      }

      if (type === 'qiniu') {
        const responseData = file.response;
        fileList.map((item, index) => {
          if (item.name === file.name) {
            fileList[index].name = responseData.key;
          }
          if (item.status !== 'done') {
            flag = false;
          }
          return null;
        });
      }

      this.setState(
        {
          loading: false,
          fileList: this.mergeFileList(fileList), // 合并图片
        },
        () => {
          // 回调，批量处理图片路径
          if (flag) {
            this.getImages();
          }
        }
      );
    }
  };

  render () {
    const { previewImage, fileList, currentIndex, needPre, needNext, preview } = this.state;
    const { totalNum, imageUploadServerHost } = this.props;

    // 配置参数
    const uploadProps = {
      action: imageUploadServerHost,
      data: this.getData,
      beforeUpload: this.beforeUpload, // 上传前钩子处理函数
      onChange: this.handleChange,
      onRemove: this.handleRemove,
      fileList,
      listType: 'picture-card',
      onPreview: this.handlePreview, // 图片点击回调
      multiple: totalNum > 1, // 是否支持多选功能
      className: styles.uploadImg,
    };
    const modalConfig = {
      visible: preview,
      title: `图片预览${fileList.length}/${currentIndex + 1}`,
      footer: null,
      onCancel: this.handlePreviewClose,
    };

    const iconStyle = {
      fontSize: 30,
    };

    return (
      <div className="clearfix">
        <Upload
          key="uploader"
          {...uploadProps}
          action="https://www.mocky.io/v2/5cc8019d300000980a055e76" // 上传地址
        >
          {/* 超过指定图片数量，隐藏上传按钮 */}
          {fileList.length >= totalNum ? null : this.uploadButton()}
          {/* <img src={this.state.fileList[0].url} alt="avatar" /> */}
        </Upload>

        {/* 弹出层显示大图 */}
        <Modal key="modal" {...modalConfig}>
          <div className={styles.needIcon_wrap}>
            {needPre ? (
              <Icon
                className={styles.needIcon_left}
                onClick={()=>this.showPreImage(currentIndex)}
                type="arrow-left"
              />
            ) : (
              <Icon
                className={styles.needIcon_leftEnd}
                type="arrow-left"
              />
              )}
            {needNext ? (
              <Icon
                className={styles.needIcon_right}
                onClick={()=>this.showNextImage(currentIndex)}
                type="arrow-right"
              />
            ) : (
              <Icon
                className={styles.needIcon_rightEnd}
                type="arrow-right"
              />
              )}
          </div>
          <img width="100%" src={previewImage} alt="" />
        </Modal>
      </div>
    );
  }
}
// 导出组件，并且载入store内数据
export default MultiUpload;
